package com.thinkgem.jeesite.modules.data.rep.service;


import com.thinkgem.jeesite.common.persistence.BaseEntity;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.modules.data.rep.dao.*;
import com.thinkgem.jeesite.modules.data.rep.entity.*;
import com.thinkgem.jeesite.modules.sys.entity.Dict;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.session.Configuration;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(readOnly = true)
public class ReportConfService {

    Logger logger =  LoggerFactory.getLogger(ReportConfService.class);

    @Autowired
    TfEcReportConfigDao reportConfigDao;
    @Autowired
    TfEcReportConfigInDao reportConfigInDao;
    @Autowired
    TfEcReportConfigOutDao reportConfigOutDao;
    @Autowired
    TfEcReportImgConfDao reportImgConfDao;
    @Autowired
    TfEcReportDownLoadDao reportDownLoadDao;

    public int saveAndUpdate(TfEcReportConfigOut configOut) {
        Date date = new Date();
        if (StringUtils.isEmpty(configOut.getOutResultId())) {
            configOut.setInDate(date);
            configOut.setUpdateTime(date);
            configOut.setInStaffId(configOut.getUpdateStaffId());
            configOut.setDelFlag(BaseEntity.DEL_FLAG_NORMAL);
            return reportConfigOutDao.insertSelective(configOut);
        } else {
            configOut.setUpdateTime(date);
            return reportConfigOutDao.updateByPrimaryKeySelective(configOut);
        }
    }

    
    public int delete(TfEcReportConfigOut configOut) {
        if(configOut.getOutResultId()!=null && configOut.getOutResultId()!=0L){
            configOut.setDelFlag(BaseEntity.DEL_FLAG_DELETE);
            configOut.setUpdateTime(new Date());
            return reportConfigOutDao.updateByPrimaryKeySelective(configOut);
        }
        return 0;
    }

    
    public List findList(TfEcReportConfigOut configOut) {
        return reportConfigOutDao.findList(configOut);
    }

    
    public Page findPage(Page<TfEcReportConfigOut> page, TfEcReportConfigOut configOut) {
        page.setList(reportConfigOutDao.findList(configOut));
        return page;
    }

    
    public TfEcReportConfigOut getConfigOutById(Long id) {
        return reportConfigOutDao.selectByPrimaryKey(id);
    }

    
    public int saveAndUpdate(TfEcReportConfigIn configIn) {
        Date date = new Date();
        if (StringUtils.isEmpty(configIn.getInConditionId())) {
            configIn.setInDate(date);
            configIn.setUpdateTime(date);
            configIn.setInStaffId(configIn.getUpdateStaffId());
            configIn.setDelFlag(BaseEntity.DEL_FLAG_NORMAL);
            return reportConfigInDao.insertSelective(configIn);
        } else {
            configIn.setUpdateTime(date);
            return reportConfigInDao.updateByPrimaryKeySelective(configIn);
        }
    }

    
    public int delete(TfEcReportConfigIn configIn) {
        if(configIn.getInConditionId()!=null && configIn.getInConditionId()!=0L){
            configIn.setDelFlag(BaseEntity.DEL_FLAG_DELETE);
            configIn.setUpdateTime(new Date());
            return reportConfigInDao.updateByPrimaryKeySelective(configIn);
        }
        return 0;
    }

    
    public List findList(TfEcReportConfigIn configIn) {
        return reportConfigInDao.findList(configIn);
    }

    
    public Page findPage(Page<TfEcReportConfigIn> page,TfEcReportConfigIn configIn) {
        page.setList(reportConfigInDao.findList(configIn));
        return page;
    }

    
    public TfEcReportConfigIn getConfigInById(Long id) {
        return reportConfigInDao.selectByPrimaryKey(id);
    }

    
    public int saveAndUpdate(TfEcReportConfig config) {
        Date date = new Date();
        if (StringUtils.isEmpty(config.getReportId())) {
            config.setInDate(date);
            config.setInStaffId(config.getUpdateStaffId());
            config.setUpdateTime(date);
            config.setDelFlag(BaseEntity.DEL_FLAG_NORMAL);
            return reportConfigDao.insertSelective(config);
        } else {
            config.setUpdateTime(date);
            return reportConfigDao.updateByPrimaryKeySelective(config);
        }
    }

    
    public int delete(TfEcReportConfig config) {
        if(config.getReportId()!=null && config.getReportId()!=0L){
            config.setDelFlag(BaseEntity.DEL_FLAG_DELETE);
            config.setUpdateTime(new Date());
            return reportConfigDao.updateByPrimaryKeySelective(config);
        }
        return 0;
    }

    
    public List findList(TfEcReportConfig config) {
        return reportConfigDao.findList(config);
    }

    
    public Page findPage(Page<TfEcReportConfig> page ,TfEcReportConfig config) {
        page.setList(reportConfigDao.findList(config));
        return page;
    }

    
    public TfEcReportConfig getConfigById(Long reportId) {
        return reportConfigDao.selectByPrimaryKey(reportId);
    }

    
    public int saveAndUpdate(TfEcReportImgConf config) {
        //Date date = new Date();
        if (StringUtils.isEmpty(config.getReportId())) {
            return reportImgConfDao.insertSelective(config);
        } else {
            return reportImgConfDao.updateByPrimaryKeySelective(config);
        }
    }

    
    public List findList(TfEcReportImgConf config) {
        return reportImgConfDao.findList(config);
    }

    
    public Page findPage(Page<TfEcReportImgConf> page, TfEcReportImgConf config) {
        page.setList(reportImgConfDao.findList(config));
        return page;
    }

    
    public TfEcReportImgConf getImgConfById(Long imgConfId) {
        return reportImgConfDao.selectByPrimaryKey(imgConfId);
    }

    
    public int delete(TfEcReportImgConf configImg) {
        return reportImgConfDao.delete(configImg);
    }


    //========== Dict ==========//
    
    public List<Dict> findSelectList(@Param(value = "sql") String sql) {
        return reportConfigDao.findSelectList(sql);
    }

    
    public List<Map<String, Object>> findResultList(TfEcReportConfig report, String filterKey) {
        //过滤器（渠道，管辖区域）
        if (!StringUtils.isEmpty(filterKey)) {
            String[] split = filterKey.split("_");
            //JDK 1.8 需要定义枚举
            //for (int i = 0; i < split.length; i++) {
            //    switch (split[i]) {
            //        default:
            //            break;
            //    }
            //}
        }
        Map<String, String> map = transferSql(report);
        report.setParamMap(map);
        transferSql(report);
        return reportConfigDao.findResultList(report);
    }

    
    public Page findResultListPage(Page page, TfEcReportConfig report,String filterKey) {
        //过滤器（渠道，管辖区域）
        if (StringUtils.isEmpty(filterKey)) {
            String[] split = filterKey.split("_");
            for (int i = 0; i < split.length; i++) {
                //JDK 1.8需要定义枚举
                //switch (split[i]) {
                //    //TODO
                //    default:
                //        break;
                //}
            }
        }
        Map<String, String> map = transferSql(report);
        report.setParamMap(map);
        report.setPage(page);
        page.setList(reportConfigDao.findResultList(report));
        return page;
    }

    /**
     * 调用存储过程
     */
    
    public int getDataByProduce(TfEcReportConfig report) {
        return reportConfigDao.updateDataByProcedure(report);
    }

    private Map<String, String> transferSql(TfEcReportConfig report)  {
        String strStart = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
                + "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">"
                + "<mapper namespace=\"com.thinkgem.jeesite.modules.report.dao.ReportProduceDao\">"
                + "<select id=\"findResultList\" parameterType=\"java.util.HashMap\" resultType=\"java.util.HashMap\">";
        String strEnd = "</select>"
                + "</mapper>";
        String sql = strStart + report.getSqlRef() + strEnd;
        logger.info("Report_sql_：{}",sql);

        InputStream inputStream = null;
        try {
            inputStream = new ByteArrayInputStream(sql.getBytes("UTF-8"));
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        Configuration conf = new Configuration();
        Map<String, XNode> sqlSeg = new HashMap<String, XNode>();
        XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(inputStream, conf, "test", sqlSeg);

        xmlMapperBuilder.parse();
        Map<String, String> map = new HashMap<String, String>();
        for (TfEcReportConfigIn config : report.getReportConfigIns()) {
            if (!StringUtils.isEmpty(config.getParamValue())) {
                map.put(config.getItemCode(), config.getParamValue());
            }
        }
        BoundSql boundSql = conf.getMappedStatement("findResultList").getBoundSql(map);
        String sqlstr = boundSql.getSql();
        List<ParameterMapping> paraMappings = boundSql.getParameterMappings();
        for (ParameterMapping para : paraMappings) {
            sqlstr = sqlstr.replaceFirst("[?]", "#{paramMap." + para.getProperty() + "}");
        }
        logger.info("Report_transql_：{}",sqlstr);
        report.setTransSql(sqlstr);
        return map;
    }


    
    public int saveReportDownLoad(ReportDownLoad reportDownLoad) {
        return reportDownLoadDao.insert(reportDownLoad);
    }

    
    public int updateReportDownLoad(ReportDownLoad reportDownLoad) {
        return reportDownLoadDao.update(reportDownLoad);
    }

    public Page<ReportDownLoad> findPage(Page<ReportDownLoad> page, ReportDownLoad entity) {
        entity.setPage(page);
        page.setList(reportDownLoadDao.findList(entity));
        return page;
    }

    public Page<ReportDownLoad> findPage(ReportDownLoad reportDownLoad) {
        return findPage(reportDownLoad.getPage(),reportDownLoad);
    }

    
    public int delete(String id) {
        ReportDownLoad reportDownLoad =new ReportDownLoad();
        reportDownLoad.setId(id);
        return reportDownLoadDao.delete(reportDownLoad);
    }

    public void delMonthData(){
        List<ReportDownLoad> reportDownLoadList=reportDownLoadDao.queryMonthList();
        for(ReportDownLoad reportDownLoad:reportDownLoadList){
            if(org.apache.commons.lang3.StringUtils.isNotEmpty(reportDownLoad.getFilePath())&& !reportDownLoad.getFilePath().contains("数据生成失败！")){
                //TFSClient.deleteFile(reportDownLoad.getFilePath()); //TODO
            }
            delete(reportDownLoad.getId());
        }
    }
}
